using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;

namespace devtm.Aop.Linq
{

    [System.Diagnostics.DebuggerDisplay("{Method}")]
	public class MethodSign
	{
        

        public IList<Type> Parameters { get; private set; }
		public string MethodName { get; private set; }


		public MethodSign(MethodInfo method)
		{
            this.Method = method;
            Parameters = method.GetMethodParameterTypes();
            MethodName = method.Name;
		}


        public override bool Equals(object obj)
        {
            return Equals(obj as MethodSign);            
        }


        public bool Equals(MethodSign obj)
        {

            if (obj == null || this.Parameters.Count != obj.Parameters.Count)
                return false;

            // compares params types...
            for (int i = 0; i < this.Parameters.Count; i++)
                if (this.Parameters[i].IsGenericParameter) continue; // open type was registered(ex: InterceptAll()) and should match any closed type
                else if (this.Parameters[i] != obj.Parameters[i])
                    return false;

            // compares method name...
            return this.MethodName == obj.MethodName;
        }

        public override int GetHashCode()
        {
            // XORs members...
            var hash = MethodName.GetHashCode();
            return Parameters.Aggregate(hash, (a, b) => a ^ b.GetHashCode());
        }

        public MethodInfo Method { get; private set; }

    }
}
